package cn.wolfcode.wolf2w.service.impl;

import cn.wolfcode.wolf2w.domain.UserInfo;
import cn.wolfcode.wolf2w.exception.LogicException;
import cn.wolfcode.wolf2w.redis.service.IUserInfoRedisService;
import cn.wolfcode.wolf2w.redis.util.RedisKeys;
import cn.wolfcode.wolf2w.respository.UserInfoRepository;
import cn.wolfcode.wolf2w.service.IUserInfoService;
import cn.wolfcode.wolf2w.util.AssertUtil;
import cn.wolfcode.wolf2w.util.Consts;
import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.List;
import java.util.UUID;

@Service
public class UserInfoServiceImpl implements IUserInfoService {

    @Autowired
    private UserInfoRepository userInfoRepository;

    @Autowired
    private IUserInfoRedisService userInfoRedisService;

    @Autowired
    private StringRedisTemplate template;

    @Override
    public void save(UserInfo userInfo) {
        userInfo.setId(null);
        userInfoRepository.save(userInfo);
    }

    @Override
    public void update(UserInfo userInfo) {
        userInfoRepository.save(userInfo);
    }

    @Override
    public void delete(String id) {
        userInfoRepository.deleteById(id);
    }

    @Override
    public UserInfo get(String id) {
        return userInfoRepository.findById(id).orElse(null);
    }

    @Override
    public List<UserInfo> list() {
        return userInfoRepository.findAll();
    }

    @Override
    public boolean checkPhone(String phone) {
        UserInfo userInfo = userInfoRepository.findByPhone(phone);
        return userInfo != null;
    }

    @Override
    public void sendVerifyCode(String phone) {

        // 创建验证码
        String code = UUID.randomUUID().toString()
                .replaceAll("-", "")
                .substring(0, 4);
        System.out.println("创建验证码" + code);

        // 创建短信
        StringBuilder stringBuilder = new StringBuilder(80);
        stringBuilder.append("【创信】您注册的短信验证码是: ")
                .append(code)
                .append(" , 请在")
                .append(Consts.VERIFY_CODE_VAI_TIME)
                .append("分钟内使用.");

        // 发短信  扩展从配置文件中获取 @Value("${sms.appkey}")
        // RestTemplate 用于发送http请求
        RestTemplate template = new RestTemplate();
        String url = "https://way.jd.com/chuangxin/dxjk?mobile={1}&content=【创信】你的验证码是：{2}，3分钟内有效！&appkey={3}";
        //String ret = template.getForObject(url, String.class, phone, stringBuilder.toString(), "7cc530de654de8251ffd98209c742dfa");
        String ret = template.getForObject(url, String.class, phone, code, "7cc530de654de8251ffd98209c742dfa");
        System.out.println("短信接口返回值:"+ret);
        // 判断短信的返回值是否包含 成功  不包含就失败了
        if (!ret.contains("SUCCESS") && !ret.contains("Success")) {
            throw new LogicException("短信发送失败");
        }

        // 将验证码存在redis中
        userInfoRedisService.setVerifyCode(phone, code);

    }

    // 之所以校验 是因为可以绕过前端校验 所以后台还得交验
    @Override
    public void regist(String phone, String nickname
            , String password, String rpassword
            , String verifyCode) {

        // 校验参数是否为空
        AssertUtil.hasLength(phone, "手机号不能为空");
        AssertUtil.hasLength(nickname, "昵称不能为空");
        AssertUtil.hasLength(password, "密码不能为空");
        AssertUtil.hasLength(rpassword, "确认密码不能为空");
        AssertUtil.hasLength(verifyCode, "验证码不能为空");

        // 校验两次输入的密码是否相等
        AssertUtil.isEquals(password, rpassword, "两次输入的密码不一致");

        // 校验手机号码是否正确

        // 校验手机号码是否唯一
        if (this.checkPhone(phone)) {
            throw new LogicException("手机号码已经被注册");
        }

        // 校验验证码是否正确
        String code = userInfoRedisService.getVerifyCode(phone);
        if (!verifyCode.equalsIgnoreCase(code)) {
            throw new LogicException("验证码失效或错误");
        }
        // 注册 创建用户
        UserInfo userInfo = new UserInfo();

        userInfo.setNickname(nickname);
        userInfo.setPhone(phone);
        userInfo.setEmail("");
        userInfo.setPassword(password);
        userInfo.setLevel(1);
        userInfo.setCity("");
        userInfo.setInfo("");
        userInfo.setHeadImgUrl("/images/default.jpg");

        userInfo.setState(UserInfo.STATE_NORMAL); // 核心属性必须自己控制

        this.save(userInfo);
    }

    @Override
    public UserInfo login(String username, String password) {
        System.out.println("登录 - login");
        //UserInfo userInfo = userInfoRepository.findUsernameAndPassword(username, password);
        // 一般不查密码 查到数据再比对性能高点
        UserInfo user = userInfoRepository.findByPhone(username);

        if (user == null || !user.getPassword().equals(password)) {
            throw new LogicException("账号或密码错误");
        }

        /********只有登录以后才有userid 所以 只能在登录后才去将数据库中的 用户收藏列表缓存到redis**********/
        // 获取到数据库中的 收藏攻略列表
        List<String> favors = user.getFavors();
        // 将 列表存到 缓存中
        // 获取记号
        String key = RedisKeys.USER_STRATEGY_FAVOR.join(user.getId());
        // 更新记号 更新vo对象
        template.opsForValue().set(key, JSON.toJSONString(favors));
        /**********************************************************************************/

        return user;
    }

    @Override
    public void updateUserFavors(String uid, List<String> sidList) {
        UserInfo userInfo = this.get(uid);
        userInfo.setFavors(sidList);
        this.update(userInfo);
    }

    @Override
    public List<UserInfo> queryByCity(String name) {
        return userInfoRepository.queryByCity(name);
    }
}


































































